using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

namespace EntityKit.Runtime
{
    public partial class BindService
    {
        private static void UIButtonClickBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIButtonClickBindAttribute>(method);
            if (attr == null) return;
            
            var button = FindTransformWithPathCache(component.transform, attr.Path)?.GetComponent<Button>();
            if (button == null)
            {
                Debug.LogError($"按钮绑定失败：路径 {attr.Path} 未找到Button组件");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"按钮方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            RecordUIComponent(component, button);
            
            button.onClick.AddListener(() => {
                method.Invoke(component, null);
            });
        }

        private static void UIToggleValueChangedBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIToggleValueChangedBindAttribute>(method);
            if (attr == null) return;
            
            var toggle = FindTransformWithPathCache(component.transform, attr.Path)?.GetComponent<Toggle>();
            if (toggle == null)
            {
                Debug.LogError($"Toggle绑定失败：路径 {attr.Path} 未找到Toggle组件");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(bool) }))
            {
                Debug.LogError($"Toggle方法签名错误：{method.Name} 必须是 void Method(bool)");
                return;
            }
            
            RecordUIComponent(component, toggle);
            
            toggle.onValueChanged.AddListener(value => {
                method.Invoke(component, new object[] { value });
            });
        }

        private static void UISliderValueChangedBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UISliderValueChangedBindAttribute>(method);
            if (attr == null) return;
            
            var slider = FindTransformWithPathCache(component.transform, attr.Path)?.GetComponent<Slider>();
            if (slider == null)
            {
                Debug.LogError($"Slider绑定失败：路径 {attr.Path} 未找到Slider组件");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(float) }))
            {
                Debug.LogError($"Slider方法签名错误：{method.Name} 必须是 void Method(float)");
                return;
            }
            
            RecordUIComponent(component, slider);
            
            slider.onValueChanged.AddListener(value => {
                method.Invoke(component, new object[] { value });
            });
        }

        private static void UIInputFieldValueChangedBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIInputFieldValueChangedBindAttribute>(method);
            if (attr == null) return;
            
            var inputField = FindTransformWithPathCache(component.transform, attr.Path)?.GetComponent<InputField>();
            if (inputField == null)
            {
                Debug.LogError($"InputField绑定失败：路径 {attr.Path} 未找到InputField组件");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(string) }))
            {
                Debug.LogError($"InputField方法签名错误：{method.Name} 必须是 void Method(string)");
                return;
            }
            
            RecordUIComponent(component, inputField);
            
            inputField.onValueChanged.AddListener(value => {
                method.Invoke(component, new object[] { value });
            });
        }

        private static void UIDropdownValueChangedBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIDropdownValueChangedBindAttribute>(method);
            if (attr == null) return;
            
            var dropdown = FindTransformWithPathCache(component.transform, attr.Path)?.GetComponent<Dropdown>();
            if (dropdown == null)
            {
                Debug.LogError($"Dropdown绑定失败：路径 {attr.Path} 未找到Dropdown组件");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(int) }))
            {
                Debug.LogError($"Dropdown方法签名错误：{method.Name} 必须是 void Method(int)");
                return;
            }
            
            RecordUIComponent(component, dropdown);
            
            dropdown.onValueChanged.AddListener(value => {
                method.Invoke(component, new object[] { value });
            });
        }

        private static void UILongClickBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UILongClickBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"长按绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"长按方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            var longPressEventComponent = gameObject.GetComponent<LongPressEventComponent>() ?? gameObject.AddComponent<LongPressEventComponent>();
            longPressEventComponent.duration = attr.Duration;
            
            RecordUIComponent(component, longPressEventComponent);
            
            longPressEventComponent.OnLongPress.AddListener(() => {
                method.Invoke(component, null);
            });
        }

        private static void UIDoubleClickBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIDoubleClickBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"双击绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"双击方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            var doubleClickEventComponent = gameObject.GetComponent<DoubleClickEventComponent>() ?? gameObject.AddComponent<DoubleClickEventComponent>();
            doubleClickEventComponent.clickInterval = attr.ClickInterval;
            
            RecordUIComponent(component, doubleClickEventComponent);
            
            doubleClickEventComponent.OnDoubleClick.AddListener(() => {
                method.Invoke(component, null);
            });
        }
    }
}